﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Web;
using System.IO;
using Newtonsoft.Json;

namespace MetaTracker.Model
{
    class RESTProcessor
    {
        #region Data and Properties
        #endregion //Data and Properties

        #region Contstructors

        public RESTProcessor()
        {

        }

        #endregion //Contstructors

        #region Methods

        public static string HttpPost(string url, string[] paramNames, string[] paramValues)
        {
            //http://rest.elkstein.org/2008/02/using-rest-in-c-sharp.html
            string result;

            HttpWebRequest request = WebRequest.Create(new Uri(url)) as HttpWebRequest;

            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";

            //build parameters string
            StringBuilder parameters = new StringBuilder();
            for (int i = 0; i < paramNames.Length; i++)
            {
                parameters.Append(paramNames[i]);
                parameters.Append("=");
                parameters.Append(HttpUtility.UrlEncode(paramValues[i]));
                parameters.Append("&");
            }

            //convert parameter string to bytes
            byte[] formData = UTF8Encoding.UTF8.GetBytes(parameters.ToString());
            request.ContentLength = formData.Length;

            //send the request
            using (Stream post = request.GetRequestStream())
            {
                post.Write(formData, 0, formData.Length);
            }

            //Grab the responce
            using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
            {
                StreamReader reader = new StreamReader(response.GetResponseStream());
                result = reader.ReadToEnd();
            }
            

            return result;
        }

        public static string HttpGet(string url)
        {
            HttpWebRequest req = WebRequest.Create(url)
                                 as HttpWebRequest;
            string result = null;
            using (HttpWebResponse resp = req.GetResponse()
                                          as HttpWebResponse)
            {
                StreamReader reader =
                    new StreamReader(resp.GetResponseStream());
                result = reader.ReadToEnd();
            }
            return result;
        }





        public static List<WithingsResult> FetchWithingsResults(int userid, int publickey)
        {
            List<WithingsResult> results = new List<WithingsResult>();

            //TODO implement this
            string[] parameterNames = new string[4];
            string[] parameterValues = new string[4];
            parameterNames[0] = "action";
            parameterValues[0] = "getmeas";
            parameterNames[1] = "userid";
            parameterValues[1] = "67754";
            parameterNames[2] = "publickey";
            parameterValues[2] = "152232292687b9c9";
            parameterNames[3] = "devtype";
            parameterValues[3] = "1";
            
            string withingsMeasurments = RESTProcessor.HttpPost("http://wbsapi.withings.net/measure?", parameterNames, parameterValues);

            WithingsMeasurmentResult withingsMeasureResult = JsonConvert.DeserializeObject<WithingsMeasurmentResult>(withingsMeasurments);


            foreach (var current in withingsMeasureResult.body.measuregrps.Where(y => y.attrib == 0 || y.attrib == 2))
            {
                results.Add(
                    new WithingsResult(current.GimmeADateTime(), 
                    current.measures.SingleOrDefault(x => x.type == 1).GimmeAWeightInPounds(),
                    current.measures.SingleOrDefault(z => z.type == 6).GimmeAFatRatio(),
                    current.measures.SingleOrDefault(w => w.type == 8).GimmeAFatMassWeight()));
            }







            return results;
        }


        #endregion //Methods
    }
}
#region Withings Fetcher data classes
public class WithingsMeasurmentResult
{
    public int Status;
    public WIthingsMeasurementResultBody body;
}
public class WIthingsMeasurementResultBody
{
    public WIthingsMeasurementResultBodyMeasurGrps[] measuregrps;
}
public class WIthingsMeasurementResultBodyMeasurGrps
{
    public int grpid;
    public int attrib;
    public Int64 date;
    public int category;
    public WIthingsMeasurementResultBodyMeasurGrpsMeasures[] measures;

    public override string ToString()
    {
        DateTime day = new DateTime(1970, 1, 1);
        day.AddDays(date);
        return day.ToString("s");
    }
    public DateTime GimmeADateTime()
    {
        DateTime day = new DateTime(1970, 1, 1);
        day = day.AddSeconds(date);
        return day;
    }


}
public class WIthingsMeasurementResultBodyMeasurGrpsMeasures
{
    public int value;
    public int type;
    public int unit;

    #region methods
    public override string ToString()
    {
        return
            ((double)value * Math.Pow(10.0, (double)unit) * 2.20462262).ToString()
            + " lbs";

    }
    public double GimmeAWeightInPounds()
    {
        return
            ((double)value * Math.Pow(10.0, (double)unit) * 2.20462262);
    }
    public double GimmeAFatRatio()
    {
        return
            ((double)value * Math.Pow(10.0, (double)unit) * 100);
    }
    public double GimmeAFatMassWeight()
    {
        return
            ((double)value * Math.Pow(10.0, (double)unit) * 2.20462262);
    }
    #endregion //methods
}
#endregion

public class WithingsResult
{
    #region Data and Properties
    private DateTime _date;
    public DateTime Date
    {
        get
        {
            return _date;
        }
        set
        {
            _date = value;
        }
    }
    private double _weight;
    public double Weight
    {
        get
        {
            return _weight;
        }
        set
        {
            _weight = value;
        }
    }
    private double _fatRatio;
    public double FatRatio
    {
        get
        {
            return _fatRatio;
        }
        set
        {
            _fatRatio = value;
        }
    }
    private double _fatMassWeight;
    public double FatMassWeight
    {
        get
        {
            return _fatMassWeight;
        }
        set
        {
            _fatMassWeight = value;
        }
    }
    #endregion //Data and Properties

    #region constructors
    public WithingsResult()
    {
    }
    public WithingsResult(DateTime date, double weight)
    {
        Date = date;
        Weight = weight;
    }
    public WithingsResult(DateTime date, double weight, double fatratio, double fatmass)
    {
        Date = date;
        Weight = weight;
        FatRatio = fatratio;
        FatMassWeight = fatmass;
    }
    #endregion //constructors

    #region Overrides
    public override string ToString()
    {
        return Date.ToString("s") + " " + Weight + " lbs";
    }
    #endregion //Overrides
}
